package com.frikinet.lifeguard.util;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

public class HibernateUtil
{
	private static final SessionFactory sessionFactory = buildSessionFactory();
	private static final Session session = createNewSession();

    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            return new AnnotationConfiguration()
	            .configure()
            	.buildSessionFactory();
        }
        catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
    
    private static Session createNewSession() {
       return sessionFactory.openSession();
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
    
    public static Session getSession()
    {
    	return session;
    }
    
    public static Session getCurrentSession()
    {
    	return getSessionFactory().getCurrentSession();
    }
    
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static <T> List<T> getElements(Class<? extends T> clazz)
    {
    	Session session = getSession();
    	session.beginTransaction();
    	List result = session.createQuery(String.format("from %s",clazz.getName())).list();
    	session.getTransaction().commit();
    	session.disconnect();
    	return result;
    }
    
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static <T> List<T> getElements(Class<? extends T> clazz, String HQL)
    {
    	Session session = getSession();
    	session.beginTransaction();
    	List result = session.createQuery(HQL).list();
    	session.getTransaction().commit();
    	session.disconnect();
    	return result;
    }
    
    public static void saveOrUpdate(List<? extends Object> list)
    {
    	Session session = getSession();
    	session.beginTransaction();
    	for(Object o: list)
    	{
    		session.saveOrUpdate(o);
    	}
    	session.getTransaction().commit();
    	session.disconnect();
    }
    
    public static void saveOrUpdate(Object o)
    {
    	Session session = getSession();
    	//session.beginTransaction();
    	session.saveOrUpdate(o);
    	//session.getTransaction().commit();
    	//session.disconnect();
    }
    
    public static void beginTransaction()
    {
    	Session session = getSession();
    	session.beginTransaction();
    }
    
    public static void commit()
    {
    	Session session = getSession();
    	session.getTransaction().commit();
    }
    
    public static void save(Object o)
    {
    	Session session = getSession();
    	session.beginTransaction();
    	session.save(o);
    	session.getTransaction().commit();
    	session.disconnect();
    }
    
    public static Object load(Class<? extends Object> clazz, Serializable id)
    {
    	Session session = getSession();
    	session.beginTransaction();
    	Object object = session.load(clazz, id);
    	session.getTransaction().commit();
    	session.disconnect();
    	return object;
    }
    
    @SuppressWarnings("unchecked")
	public static <T> void checkAndSave(T o, Serializable id)
    {
    	Session session = getSession();
    	session.beginTransaction();
    	T object = (T)session.get(o.getClass(), id);
    	if(object == null) //save
    	{
    		session.save(o);
    	}
    	else //update
    	{
    		session.update(object);
    	}
    	session.getTransaction().commit();
    	session.disconnect();
    }
    
    public static void delete(Object o)
    {
    	Session session = getSession();
    	session.beginTransaction();
    	session.delete(o);
    	session.getTransaction().commit();
    	session.disconnect();
    }
    
    public static void persist(Object o)
    {
    	Session session = getSession();
    	session.beginTransaction();
    	session.persist(o);
    	session.getTransaction().commit();
    	session.disconnect();
    }
    
    @SuppressWarnings("unchecked")
	public static <T> T get(Class<T> clazz, Serializable id)
    {
    	Session session = getSession();
    	session.beginTransaction();
    	T o = (T)session.get(clazz, id);
    	session.getTransaction().commit();
    	session.disconnect();
    	return o;
    }
    
    @SuppressWarnings("unchecked")
	public static <T> T get(Class<T> clazz, String field, String value)
    {
    	Session session = getSession();
    	Query query = session.createQuery(String.format("select c from %s c where c.%s='%s'",clazz.getName(),field,value));
    	return (T)query.uniqueResult();
    }
    
    @SuppressWarnings("unchecked")
	public static <T> T get(Class<? extends T> clazz, String HQL)
    {
    	Session session = getSession();
    	session.beginTransaction();
    	List<T> result = session.createQuery(HQL).list();
    	session.getTransaction().commit();
    	session.disconnect();
    	return result.get(0);
    }
   
}
